<template>
  <div id="chart"></div>
</template>

<script>
import { Graph } from "@antv/x6";

// 父容器 随着子元素的移动 自动改变 容器大小

export default {
  name: "Group",
  methods: {
    createGraph() {
      const graph = new Graph({
        container: document.getElementById("chart"),
        width: window.innerWidth,
        height: window.innerHeight,
        grid: true,
        embedding: {
          enabled: true,
        },
        highlighting: {
          embedding: {
            name: "stroke",
            args: {
              padding: -1,
              attrs: {
                stroke: "#73d13d",
              },
            },
          },
        },
      });

      const source = graph.addNode({
        x: 80,
        y: 100,
        width: 80,
        height: 40,
        label: "Child",
        zIndex: 10,
        attrs: {
          body: {
            stroke: "none",
            fill: "#3199FF",
          },
          label: {
            fill: "#fff",
            fontSize: 12,
          },
        },
      });

      const target = graph.addNode({
        x: 280,
        y: 80,
        width: 80,
        height: 40,
        label: "Child",
        zIndex: 10,
        attrs: {
          body: {
            stroke: "none",
            fill: "#47C769",
          },
          label: {
            fill: "#fff",
            fontSize: 12,
          },
        },
      });

      const parent = graph.addNode({
        x: 40,
        y: 40,
        width: 360,
        height: 160,
        zIndex: 1,
        label: "Parent",
        attrs: {
          body: {
            fill: "#fffbe6",
            stroke: "#ffe7ba",
          },
          label: {
            fontSize: 12,
          },
        },
      });

      parent.addChild(source);
      parent.addChild(target);

      let ctrlPressed = false;
      const embedPadding = 20;

      graph.on("node:embedding", ({ e }) => {
        ctrlPressed = e.metaKey || e.ctrlKey;
      });

      graph.on("node:embedded", () => {
        ctrlPressed = false;
      });

      graph.on("node:change:size", ({ node, options }) => {
        if (options.skipParentHandler) {
          return;
        }

        const children = node.getChildren();
        if (children && children.length) {
          node.prop("originSize", node.getSize());
        }
      });

      graph.on("node:change:position", ({ node, options }) => {
        if (options.skipParentHandler || ctrlPressed) {
          return;
        }

        const children = node.getChildren();
        if (children && children.length) {
          node.prop("originPosition", node.getPosition());
        }

        const parent = node.getParent();
        if (parent && parent.isNode()) {
          let originSize = parent.prop("originSize");
          if (originSize == null) {
            originSize = parent.getSize();
            parent.prop("originSize", originSize);
          }

          let originPosition = parent.prop("originPosition");
          if (originPosition == null) {
            originPosition = parent.getPosition();
            parent.prop("originPosition", originPosition);
          }

          let x = originPosition.x;
          let y = originPosition.y;
          let cornerX = originPosition.x + originSize.width;
          let cornerY = originPosition.y + originSize.height;
          let hasChange = false;

          const children = parent.getChildren();
          if (children) {
            children.forEach((child) => {
              const bbox = child.getBBox().inflate(embedPadding);
              const corner = bbox.getCorner();

              if (bbox.x < x) {
                x = bbox.x;
                hasChange = true;
              }

              if (bbox.y < y) {
                y = bbox.y;
                hasChange = true;
              }

              if (corner.x > cornerX) {
                cornerX = corner.x;
                hasChange = true;
              }

              if (corner.y > cornerY) {
                cornerY = corner.y;
                hasChange = true;
              }
            });
          }

          if (hasChange) {
            parent.prop(
              {
                position: { x, y },
                size: { width: cornerX - x, height: cornerY - y },
              },
              { skipParentHandler: true }
            );
          }
        }
      });
    },
  },
  mounted() {
    this.createGraph();
  },
};
</script>

<style>
</style>